#!/bin/bash
# vim: et ts=4 sw=4 ft=sh

# Interesting post on max line length:
# http://stackoverflow.com/questions/88942/why-should-python-pep-8-specify-a-maximum-line-length-of-79-characters

RUFF_CMD='ruff check'
ESLINT_CMD='npx eslint'
BIOME_CMD='npx @biomejs/biome format --colors=force'
STYLELINT_CMD='npx stylelint'

RED=$(echo -e $"\033[1;31m")
YELLOW=$(echo -e $"\033[0;33m")
CYAN=$(echo -e $"\033[0;36m")
RESET=$(echo -e $"\033[0;0m")
BRIGHTYELLOW=$(echo -e $"\033[1;33m")
WHITE=$(echo -e $"\033[1;37m")

RE="s/\([^:]*\):\([0-9]*\):\([0-9]*\): \([EW][0-9]*\) \(.*\)/$WHITE[$CYAN\1$RESET $BRIGHTYELLOW\2:\3$WHITE] $RED\4 $YELLOW\5$RESET/g"
STATUS=0

_get_files() {
    local i
    unset FILES
    while IFS= read -r -d $'\0' file; do
        FILES[i++]="$file"
    done < <(git diff --name-only --diff-filter=ACMR --staged -z "$@")
}

# Most spammy checks first so the most likely useful ones are at the
# bottom and thus less likely to scroll out of view immediately

# Stylelint
_get_files '*.scss' '*.css'
if [[ ${#FILES[@]} -ne 0 ]]; then
    if ! RESULT=$(FORCE_COLOR=1 $STYLELINT_CMD -q "${FILES[@]}"); then
        STATUS=1
        echo "${RED}There are SCSS errors in your code:${RESET}"
        echo "$RESULT"
    elif [[ -n "$RESULT" ]] ; then
        STATUS=1
        echo "${BRIGHTYELLOW}There are SCSS warnings in your code:${RESET}"
        echo "$RESULT"
    fi
fi


# ESLint + Biome
_get_files '*.js' '*.jsx' '*.ts' '*.tsx' '*.mjs'
if [[ ${#FILES[@]} -ne 0 ]]; then
    if ! RESULT=$($ESLINT_CMD --color "${FILES[@]}"); then
        STATUS=1
        echo "${RED}There are JS errors in your code:${RESET}"
        echo "$RESULT"
    elif [[ -n "$RESULT" ]] ; then
        STATUS=1
        echo "${BRIGHTYELLOW}There are JS warnings in your code:${RESET}"
        echo "$RESULT"
    fi

    if ! RESULT=$($BIOME_CMD "${FILES[@]}" 2>&1); then
        STATUS=1
        echo "${RED}There are formatting issues in your code:${RESET}"
        echo "$RESULT"
        echo
    fi
fi


# ruff
_get_files '*.py'
if [[ ${#FILES[@]} -ne 0 ]]; then
    if ! RESULT=$(CLICOLOR_FORCE=1 $RUFF_CMD "${FILES[@]}"); then
        STATUS=1
        echo "${RED}There are ruff python issues in your code:${RESET}"
        echo "$RESULT"
        echo
    fi
fi


# isort
if ! RESULT=$(python -c 'import sys; from isort.hooks import git_hook; sys.exit(git_hook(strict=True))' 2>&1); then
    STATUS=1
    echo
    echo "${RED}There are isort issues in your code:${RESET}"
    echo "$RESULT"
    echo
    echo "${CYAN}Run this command to sort the imports:${RESET}"
    echo "git diff --staged --name-only --diff-filter d '*.py' | xargs -d'\n' isort"
fi


if [[ $STATUS != 0 ]] ; then
    # claim stdin back
    exec < /dev/tty
    echo
    read -r -p "${RED}Do you wish to commit it anyway ${CYAN}[${WHITE}y${CYAN}/${WHITE}N${CYAN}]${RESET}? " yn
    case $yn in
        [Yy]* ) exit 0;;
        [Nn]* ) exit $STATUS;;
        * ) exit $STATUS;;
    esac
    # close stdin
    exec <&-
fi

exit $STATUS
